package hedron.dialog;

import static hedron.i18n.Internationalization._;
import hedron.Application;
import hedron.db.model.Stock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
public class GroupingDialog extends AbstractDialog {

	Stock groupingStock;
	ArrayList<Stock> allStocks;
	ArrayList<Stock> groupedStocks;

	Text filter;
	Table stocksTable;
	Table groupedTable;

	Comparator<Stock> groupedStocksComparator;

	public GroupingDialog(Shell parentShell, Stock groupingStock) {
		super(parentShell);
		if (groupingStock == null) {
			throw new IllegalArgumentException("groupedStock may not be null");
		}
		this.groupingStock = groupingStock;
		allStocks = Application.STOCKS.getStocks(null, null, null);
		groupedStocks = Application.STOCKS.getGroupedStocks(groupingStock);

		groupedStocksComparator = new Comparator<Stock>() {
			@Override
			public int compare(Stock o1, Stock o2) {
				return o1.STOCK_NAME.compareToIgnoreCase(o2.STOCK_NAME);
			}
		};
	}

	@Override
	public void create() {
		super.create();
		setTitle(_("Dialog.Grouping.Title") + " " + groupingStock.STOCK_NAME);
		setMessage(_("Dialog.Grouping.Message"), 0);
	}

	void refresh() {
		int selection;
		allStocks = Application.STOCKS.getStocks(filter.getText(), null, null);
		stocksTable.setRedraw(false);
		selection = stocksTable.getSelectionIndex();
		stocksTable.removeAll();
		for (Stock stock : allStocks) {
			TableItem item = new TableItem(stocksTable, SWT.NONE);
			item.setData(stock);
			item.setText(0, stock.STOCK_NAME);
		}
		stocksTable.getColumn(0).pack();
		if (selection < stocksTable.getItemCount()) {
			stocksTable.setSelection(selection);
		}
		stocksTable.setRedraw(true);

		groupedTable.setRedraw(false);
		groupedTable.removeAll();
		for (Stock stock : groupedStocks) {
			TableItem item = new TableItem(groupedTable, SWT.NONE);
			item.setData(stock);
			item.setText(0, stock.STOCK_NAME);
			item.setText(1, String.valueOf(stock.QTY));
		}
		groupedTable.getColumn(0).pack();
		groupedTable.getColumn(1).pack();
		groupedTable.setRedraw(true);
	}

	private void addStockForGrouping() {
		int selection = stocksTable.getSelectionIndex();
		if (selection >= 0) {
			Stock stock = (Stock) stocksTable.getItem(selection).getData();
			if (stock.getID() != groupingStock.getID()) {
				Stock updateStock = null;
				for (Stock gstock : groupedStocks) {
					if (gstock.getID() == stock.getID()) {
						updateStock = gstock;
					}
				}
				if (updateStock == null) {
					groupedStocks.add(stock);
				}
				Collections.sort(groupedStocks, groupedStocksComparator);
				refresh();
			}
		}
	}

	private void removeStockFromGrouping() {
		int selection = groupedTable.getSelectionIndex();
		if (selection >= 0 && selection < groupedStocks.size()) {
			groupedStocks.remove(selection);
			refresh();
		}
	}

	@Override
	protected void okPressed() {
		Application.STOCKS.updateGroupedStocks(groupingStock, groupedStocks);
	}

	@Override
	void createContent(Composite parent) {

		Composite grid = new Composite(parent, 0);
		grid.setLayoutData(new GridData(GridData.FILL_BOTH));

		{// set parent layout
			GridLayout layout = new GridLayout();
			layout.numColumns = 3;
			grid.setLayout(layout);
		}
		{
			GridData gd = new GridData(GridData.FILL_BOTH);
			gd.widthHint = 600;
			gd.heightHint = 300;
			grid.setLayoutData(gd);
		}

		{
			Composite area = new Composite(grid, 0);
			area.setLayoutData(new GridData(GridData.FILL_BOTH));
			{// set parent layout
				GridLayout layout = new GridLayout();
				layout.numColumns = 1;
				area.setLayout(layout);
			}
			{// filter
				Text text = new Text(area, SWT.BORDER);
				GridData gdata = new GridData(GridData.FILL, GridData.BEGINNING, true, false);
				text.setLayoutData(gdata);
				text.addKeyListener(new KeyListener() {
					@Override
					public void keyReleased(KeyEvent e) {
						refresh();
					}

					@Override
					public void keyPressed(KeyEvent e) {}
				});
				filter = text;
			}
			{
				Table table = new Table(area, SWT.FULL_SELECTION | SWT.BORDER);
				table.setLayoutData(new GridData(GridData.FILL_BOTH));

				{
					TableColumn column = new TableColumn(table, SWT.NONE);
					column.setText(_("Column.Stocks"));
				}
				table.setHeaderVisible(true);
				table.setLinesVisible(true);

				table.addListener(SWT.MouseDoubleClick, new Listener() {
					@Override
					public void handleEvent(Event event) {
						addStockForGrouping();
					}
				});

				stocksTable = table;
			}
		}
		{
			Composite area = new Composite(grid, 0);
			area.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, false, false));
			{// set parent layout
				GridLayout layout = new GridLayout();
				layout.numColumns = 1;
				area.setLayout(layout);
			}
			{// add
				Button button = new Button(area, SWT.PUSH);
				button.setText(">>");
				GridData gdata = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false);
				gdata.widthHint = 30;
				button.setLayoutData(gdata);
				button.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent event) {
						addStockForGrouping();
					}
				});
			}
			{// remove
				Button button = new Button(area, SWT.PUSH);
				button.setText("<<");
				GridData gdata = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false);
				gdata.widthHint = 30;
				button.setLayoutData(gdata);
				button.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent event) {
						removeStockFromGrouping();
						refresh();
					}
				});
			}
		}
		{
			Composite area = new Composite(grid, 0);
			area.setLayoutData(new GridData(GridData.FILL_BOTH));
			{// set parent layout
				GridLayout layout = new GridLayout();
				layout.numColumns = 1;
				area.setLayout(layout);
			}
			{
				final Table table = new Table(area, SWT.FULL_SELECTION | SWT.BORDER);
				table.setLayoutData(new GridData(GridData.FILL_BOTH));

				{
					TableColumn column = new TableColumn(table, SWT.NONE);
					column.setText(_("Column.Stocks"));
				}
				{
					TableColumn column = new TableColumn(table, SWT.NONE | SWT.RIGHT);
					column.setText(_("Column.Quantity"));
				}
				table.setHeaderVisible(true);
				table.setLinesVisible(true);

				final TableEditor editor = new TableEditor(table);
				editor.horizontalAlignment = SWT.RIGHT;
				editor.grabHorizontal = true;
				editor.minimumWidth = 50;
				// editing the second column
				final int EDITABLECOLUMN = 1;
				table.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						// Clean up any previous editor control
						Control oldEditor = editor.getEditor();
						if (oldEditor != null) oldEditor.dispose();

						// Identify the selected row
						final TableItem item = (TableItem) e.item;
						if (item == null) return;

						// The control that will be the editor must be a child
						// of the Table
						Text newEditor = new Text(table, SWT.NONE | SWT.RIGHT);
						newEditor.setData(item.getData());
						newEditor.setText(item.getText(EDITABLECOLUMN));
						newEditor.addModifyListener(new ModifyListener() {
							public void modifyText(ModifyEvent me) {
								Text text = (Text) editor.getEditor();
								editor.getItem().setText(EDITABLECOLUMN, text.getText());
								Stock stock = (Stock) item.getData();
								try {
									stock.QTY = Long.parseLong(text.getText(), 10);
								} catch (Exception e) {
									stock.QTY = 0L;
								}
							}
						});
						newEditor.selectAll();
						newEditor.setFocus();
						editor.setEditor(newEditor, item, EDITABLECOLUMN);
					}
				});

				groupedTable = table;
			}
		}
		refresh();
	}

	@Override
	void createFooter(Composite parent) {
		((GridLayout) parent.getLayout()).numColumns = 1;
		Composite grid = new Composite(parent, 0);
		grid.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false));

		{// set grid layout
			GridLayout layout = new GridLayout();
			layout.numColumns = 3;
			grid.setLayout(layout);
		}
		{// cell 1 - empty text
			Label label = new Label(grid, 0);
			label.setText("");
			GridData gdata = new GridData(GridData.FILL, GridData.END, true, false);
			gdata.heightHint = 20;
			label.setLayoutData(gdata);
			label.setFocus();
		}
		{// cancel
			Button button = new Button(grid, SWT.PUSH);
			button.setText("Cancel");
			GridData gdata = new GridData(GridData.BEGINNING, GridData.END, false, false);
			gdata.heightHint = 20;
			gdata.widthHint = 100;
			button.setLayoutData(gdata);
			button.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					setReturnCode(CANCEL);
					close();
				}
			});
		}
		{// ok
			Button button = new Button(grid, SWT.PUSH);
			button.setText("OK");
			GridData gdata = new GridData(GridData.END, GridData.END, false, false);
			gdata.heightHint = 20;
			gdata.widthHint = 100;
			button.setLayoutData(gdata);
			button.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					setReturnCode(OK);
					okPressed();
					close();
				}
			});
		}
	}
}
